// Copyright (c) 1996-2002 John Lyon-Smith. All rights reserved.

#pragma once

#include <wxtl\SyncObject.h>

namespace wxtl
{
	class Mutex : public SyncObject
	{
	public:
		Mutex()
		{
		}
		Mutex(Mutex &mutex) throw() :
			SyncObject(mutex)
		{
		}
		explicit Mutex(HANDLE hMutex) throw() :
			SyncObject(hMutex)
		{
		}
		~Mutex() 
		{
		}
		Mutex& operator=(Mutex& h) throw()
		{
			return (Mutex&)Handle::operator=(h);
		}

		bool create(const TCHAR* pszName = NULL, bool bInitialOwner = false, LPSECURITY_ATTRIBUTES psa = NULL)
		{
			_ASSERTE(!isValid());
			return ((m_h = ::CreateMutex(psa, bInitialOwner, pszName)) != NULL);
		}
		bool open(const TCHAR* pszName = NULL, DWORD dwAccess = MUTEX_ALL_ACCESS, bool bInheritable = false)
		{
			_ASSERTE(!isValid());
			return ((m_h = ::OpenMutex(dwAccess, bInheritable, pszName)) != NULL);
		}

		bool release()
		{
			_ASSERTE(isValid());
			return (ReleaseMutex(m_h) == TRUE);
		}
	};	

	class Lock
	{
	public:
		Lock(Mutex& mtx)
			:m_xMutex(mtx)
		{
			lock();
		}
		~Lock()
		{
			unlock();
		}
		void lock(void)
		{
			m_xMutex.wait();
		}
		void unlock(void)
		{
			m_xMutex.release();
		}
	private:
		Lock& operator=(const Lock&);
	protected:
		Mutex& m_xMutex;
	};
}
